# Copyright (C) 2006, 2007  Stephane Alnet
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
# 

#
# For more information visit http://carrierclass.net/
#
use strict; use warnings;

package CCNCore::Provision::Database;
use base qw(CCNCore::Provision::Base);

use CCNCore::Home;

# MUST be present in the subclasses
# sub model_name();
# sub get_db_names();

# ---- Normally these do not need to be subclassed.

sub run()
{
    my $self = shift;
    return if $self->p->force_manager;

    return unless defined $self->p->{db_member} and $self->p->system_pk == $self->p->primary_db_server;

    # Commit this module at commit time.
    # Note: Only use this module to recover a failed bootstrap.
    COMMIT_MODULE(ref($self));
}

sub commit($)
{
    my $self = shift;
    my $c = shift;

    $self->log(ref($self)."::commit()\n");

    if($self->bootstrapping)
    {
        $self->log(ref($self)."::bootstrap()\n");
        $self->bootstrap($c);
    }
    else
    {
        $self->log(ref($self)."::update_schema()\n");
        $self->update_schema($c);
    }

    $self->log(ref($self)."::grants()\n");
    $self->grants($c);

    $self->log(ref($self)."::overwrite()\n");
    $self->overwrite($c);
}

sub grants($)
{
    my $self = shift;
    my $c    = shift;
    $self->log(ref($self)."::grants: nothing to do\n");
}

# ------- Tools -------

# Where to save the dump from the live database
sub dump_file()
{
    my $self = shift;
    return CCNCore::Home::config.'/local/'.$self->model_name().'.dump.sqlite3';
}

# ----- More tools ----

# database_exists is probably redundant (at least we never test differently because of it)
# but let's keep it for now.
sub __database_exists($)
{
    my $db_name = shift;

    # Copied from CCNCore::Database::Local
    my $dbi_info = "DBI:mysql:database=${db_name}";
    my $login = '';
    my $password = '';
    
    # Copied from CCN::Database
    use DBI;
    
    my $dbh = DBI->connect(
        $dbi_info, $login, $password, 
        { RaiseError => 0, AutoCommit => 1 }
    );
    my $result = $dbh ? 1 : 0;
    undef $dbh;
    return $result;
}

sub database_looksgood($)
{
    my $self = shift;
    my $db_name = shift;
    
    # Copied from CCNCore::Database::Local
    my $dbi_info = "DBI:mysql:database=${db_name}";
    my $login = '';
    my $password = '';
    
    # Copied from CCN::Database
    use DBI;
    
    my $dbh = DBI->connect(
        $dbi_info, $login, $password, 
        { RaiseError => 0, AutoCommit => 1 }
    );
    return 0 if not $dbh;

    my $model = $self->model_name();
    my $sth = $dbh->prepare(<<"SQL");
        SELECT COUNT(*) FROM "ccn_ok_${model}" WHERE name = ?
SQL
    return 0 if not $sth;

    my $rv = $sth->execute($db_name.'-'.$model);

    $sth->finish(),
    return 0 if not $rv;

    my ($count) = $sth->fetchrow_array();
    $sth->finish();

    undef $dbh;
    
    return $count > 0;
}

sub database_cleargood($)
{
    my $self = shift;
    my $db_name = shift;
    
    # Copied from CCNCore::Database::Local
    my $dbi_info = "DBI:mysql:database=${db_name}";
    my $login = '';
    my $password = '';
    
    # Copied from CCN::Database
    use DBI;
    
    my $dbh = DBI->connect(
        $dbi_info, $login, $password, 
        { RaiseError => 0, AutoCommit => 1 }
    );
    $self->die ("Unable to connect to $db_name") if not $dbh;

    my $model = $self->model_name();
    $dbh->do(qq(DROP TABLE IF EXISTS "ccn_ok_${model}"));
    undef $dbh;
}

sub database_done($)
{
    my $self = shift;
    my $db_name = shift;

    # Copied from CCNCore::Database::Local
    my $dbi_info = "DBI:mysql:database=${db_name}";
    my $login = '';
    my $password = '';
    
    use CCN::Database;
    my $db = new CCN::Database($dbi_info,$login,$password);

    my $model = $self->model_name();
    $db->sql_do(qq(DROP TABLE IF EXISTS "ccn_ok_${model}"));
    $db->sql_do(qq(CREATE TABLE IF NOT EXISTS "ccn_ok_${model}"(name TEXT)));
    $db->sql_do(qq(INSERT INTO "ccn_ok_${model}" VALUES (?)),$db_name.'-'.$model);    
}

1;